import sys
import os
import re
import random
import numpy as np
import copy
import time


class Sever_Machine:
    def __init__(self, Sever):
        self.Model = Sever[0]  # 型号
        self.CPU_cores = Sever[1]  # CPU核数
        self.Memory_Size = Sever[2]  # 内存大小
        self.Hardware_cost = Sever[3]  # 硬件成本
        self.Energy_cost = Sever[4]  # 能耗成本
        self.No_ = 0
        self.Node_A = []  # 当前A节点剩余核数内存情况
        self.Node_B = []  # 当前B节点剩余核数内存情况
        self.Both = []
        self.assigned = []
        self.assigned_Node = []
        self.rest_CPU_A = self.CPU_cores / 2
        self.rest_Memory_A = self.Memory_Size / 2
        self.rest_CPU_B = self.CPU_cores / 2
        self.rest_Memory_B = self.Memory_Size / 2

    def add_to_Node_A(self, V):
        self.Node_A.append(V)
        self.assigned.append(V[4])
        self.assigned_Node.append(1)
        self.rest_Memory_A -= V[2]
        self.rest_CPU_A -= V[1]

    def add_to_Node_B(self, V):
        self.Node_B.append(V)
        self.assigned.append(V[4])
        self.assigned_Node.append(2)
        self.rest_Memory_B -= V[2]
        self.rest_CPU_B -= V[1]

    def add_to_both(self, V):
        self.Both.append(V)
        self.assigned.append(V[4])
        self.assigned_Node.append(0)
        self.rest_CPU_A -= V[1] / 2
        self.rest_Memory_A -= V[2] / 2
        self.rest_CPU_B -= V[1] / 2
        self.rest_Memory_B -= V[2] / 2

    def Judge_whether_to_insert(self, V):
        K = []
        if V[3] == 1:
            if self.rest_CPU_A >= V[1] / 2 and self.rest_CPU_B >= V[1] / 2 and \
                    self.rest_Memory_A >= V[2] / 2 and self.rest_Memory_B >= V[2] / 2:
                self.add_to_both(V)
                return True
            else:
                return False
        if V[3] == 0:
            if self.rest_CPU_A >= V[1] and self.rest_Memory_A >= V[2]:
                K.append(1)
            if self.rest_CPU_B >= V[1] and self.rest_Memory_B >= V[2]:
                K.append(2)
            if len(K) == 2:
                if random.choice(K) == 1:
                    self.add_to_Node_A(V)
                else:
                    self.add_to_Node_B(V)
                return True
            elif len(K) == 1:
                if K[0] == 1:
                    self.add_to_Node_A(V)
                else:
                    self.add_to_Node_B(V)
                return True
            else:
                return False

    def del_Virtual(self, V):
        K = self.assigned.index(V[4])
        K_1 = self.assigned_Node
        M = self.assigned_Node[K]
        if M == 0:
            self.rest_CPU_A += V[1]
            self.rest_Memory_A += V[2]
        if M == 1:
            self.rest_CPU_B += V[1]
            self.rest_Memory_B += V[2]
        if M == 0:
            self.rest_CPU_A += V[1] / 2
            self.rest_Memory_A += V[2] / 2
            self.rest_CPU_B += V[1] / 2
            self.rest_Memory_B += V[2] / 2
        self.assigned.remove(V[4])
        del self.assigned_Node[K]
        O = self.assigned_Node

    def Node_Situation(self):
        Load_CPU_A = self.CPU_cores / 2 - self.rest_CPU_A
        Load_CPU_B = self.CPU_cores / 2 - self.rest_CPU_B
        Load_M_A = self.Memory_Size / 2 - self.rest_Memory_A
        Load_M_B = self.Memory_Size / 2 - self.rest_Memory_B
        return Load_CPU_A, Load_CPU_B, Load_M_A, Load_M_B

    def Use_situation(self):
        Load_CPU = self.CPU_cores - self.rest_CPU_A - self.rest_CPU_A
        Load_M = self.Memory_Size - self.rest_Memory_A - self.rest_Memory_B
        return Load_CPU, Load_M

    def replace_machine(self, Sev):
        self.Model = Sev[0]  # 型号
        self.CPU_cores = Sev[1]  # CPU核数
        self.Memory_Size = Sev[2]  # 内存大小
        self.Hardware_cost = Sev[3]  # 硬件成本
        self.Energy_cost = Sev[4]  # 能耗成本


class daily_situation:
    def __init__(self, Sever, Virtual, use_Case):
        self.Sever = Sever
        self.Virtual = Virtual
        self.Virtual_name = list(np.array(Virtual)[:, 0])
        self.use_Case = use_Case
        self.days = 0.2 * (len(use_Case))
        self.Sever_have = []
        self.Configured = []

    def Sever_Select(self, K):
        V = copy.copy(K)
        Selected_Sever = []
        Select = random.choice(self.Sever)
        Select_i = Sever_Machine(Select)
        while V != []:
            Select_V = random.choice(V)
            result = Select_i.Judge_whether_to_insert(Select_V)
            if result == True:  # 随机配置
                V.remove(Select_V)
                if V == []:
                    Selected_Sever.append(Select_i)
                    break
            if result == False:
                for i in range(len(V)):
                    result = Select_i.Judge_whether_to_insert(V[i])
                    if result == True:
                        V.remove(V[i])
                        break
                if result == False and i >= len(V) - 1:
                    Selected_Sever.append(Select_i)
                    Select = random.choice(self.Sever)
                    Select_i = Sever_Machine(Select)
        return Selected_Sever
        return Selected_Sever

    def add_to_old(self, S, V):
        for i in range(len(S)):
            if V != []:
                random.shuffle(V)
                for V_i in V:
                    result = S[i].Judge_whether_to_insert(V_i)
                    if result == True:
                        V.remove(V_i)
        return S, V

    def transfer(self, Sever, V_total):
        Transferable_num = int(len(V_total) * 5 / 1000)
        if Transferable_num > 0:
            # for i in range(len())
            pass
        else:
            pass
        return Sever

    def Virtual_use(self):
        User_total = []
        V_Total = []
        User_used_Sever = []
        Coun = 0
        Total_Host = []
        for i in range(len(self.use_Case)):
            daily_used_Sever = []
            Old_Sever_unfull_i = []
            daily_Buy_Host = []
            V_T = []
            Host_buy = Sever_Machine(random.choice(self.Sever))
            daily_Buy_Host.append(Host_buy)
            for j in range(len(self.use_Case[i])):
                if self.use_Case[i][j][0] == 'add':
                    V_I = copy.copy(self.Virtual[self.Virtual_name.index(self.use_Case[i][j][1])])
                    V_I.append(self.use_Case[i][j][2])
                    V_Total.append(V_I)
                    V_T.append(V_I)
                    User_total.append(self.use_Case[i][j][2])
                    if Old_Sever_unfull_i != []:
                        for Old_i in Old_Sever_unfull_i:
                            result = Old_i.Judge_whether_to_insert(V_I)
                            if result == True:
                                User_used_Sever.append(Old_i)
                                daily_used_Sever.append(Old_i)
                                Old_Sever_unfull_i.remove(Old_i)
                                break
                        if result == False:
                            result = Host_buy.Judge_whether_to_insert(V_I)
                            if result == True:
                                User_used_Sever.append(Host_buy)
                                daily_used_Sever.append(Host_buy)
                            else:
                                Host_buy = Sever_Machine(random.choice(self.Sever))
                                daily_Buy_Host.append(Host_buy)
                                Host_buy.Judge_whether_to_insert(V_I)
                                daily_used_Sever.append(Host_buy)
                                User_used_Sever.append(Host_buy)
                    else:
                        result = Host_buy.Judge_whether_to_insert(V_I)
                        if result == True:
                            User_used_Sever.append(Host_buy)
                            daily_used_Sever.append(Host_buy)
                        else:
                            Host_buy = Sever_Machine(random.choice(self.Sever))
                            daily_Buy_Host.append(Host_buy)
                            Host_buy.Judge_whether_to_insert(V_I)
                            daily_used_Sever.append(Host_buy)
                            User_used_Sever.append(Host_buy)
                if self.use_Case[i][j][0] == 'del':
                    V_name = self.use_Case[i][j][0]
                    User_Site = User_total.index(self.use_Case[i][j][1])
                    Vm = V_Total[User_Site]
                    try:
                        Sever_use = User_used_Sever[User_Site]
                        Sever_use.del_Virtual(Vm)
                        Old_Sever_unfull_i.append(Sever_use)
                        User_total.remove(User_total[User_Site])
                        if V_Total[User_Site] in V_T:
                            V_site = V_T.index(V_Total[User_Site])
                            del daily_used_Sever[V_site]
                            V_T.remove(V_Total[User_Site])
                        del V_Total[User_Site]
                        del User_used_Sever[User_Site]
                    except:
                        for Vm_i in range(len(User_used_Sever)):
                            if self.use_Case[i][j][1] in User_used_Sever[Vm_i].assigned:
                                User_used_Sever[Vm_i].del_Virtual(Vm)
                                Old_Sever_unfull_i.append(User_used_Sever[Vm_i])
                                User_total.remove(User_total[Vm_i])
                                if Vm in V_T:
                                    V_site = V_T.index(Vm)
                                    del daily_used_Sever[V_site]
                                    V_T.remove(Vm)
                                V_Total.remove(Vm)
                                del User_used_Sever[Vm_i]
            Total_Host.extend(daily_Buy_Host)
            Q = []
            for S_k in range(len(daily_Buy_Host)):
                Q.append(daily_Buy_Host[S_k].Model)
            Q_set = set(Q)
            Q_num = len(list(Q_set))
            print('(Purchase,', Q_num, ')')
            for Q_i in Q_set:
                print('(', Q_i, ',', Q.count(Q_i), ')')
            print('(migration,', 0, ')')
            for Q_seti in Q_set:
                for day_i in daily_Buy_Host:
                    if day_i.Model == Q_seti:
                        day_i.No_ = Coun
                        Coun += 1
            for V_k in range(len(V_T)):
                try:
                    if daily_used_Sever[V_k].assigned_Node[daily_used_Sever[V_k].assigned.index(V_T[V_k][4])] == 1:
                        print('(', daily_used_Sever[V_k].No_, ',', 'A', ')')
                    if daily_used_Sever[V_k].assigned_Node[daily_used_Sever[V_k].assigned.index(V_T[V_k][4])] == 2:
                        print('(', daily_used_Sever[V_k].No_, ',', 'B', ')')
                    if daily_used_Sever[V_k].assigned_Node[daily_used_Sever[V_k].assigned.index(V_T[V_k][4])] == 0:
                        print('(', daily_used_Sever[V_k].No_, ')')
                except:
                    for day_j in range(len(daily_used_Sever)):
                        if V_T[V_k][4] in daily_used_Sever[day_j].assigned:
                            if daily_used_Sever[day_j].assigned_Node[
                                daily_used_Sever[day_j].assigned.index(V_T[day_j][4])] == 1:
                                print('(', daily_used_Sever[day_j].No_, ',', 'A', ')')
                            if daily_used_Sever[day_j].assigned_Node[
                                daily_used_Sever[day_j].assigned.index(V_T[day_j][4])] == 2:
                                print('(', daily_used_Sever[day_j].No_, ',', 'B', ')')
                            if daily_used_Sever[day_j].assigned_Node[
                                daily_used_Sever[day_j].assigned.index(V_T[day_j][4])] == 2:
                                print('(', daily_used_Sever[day_j].No_, ')')


def Get_data():
    serves = []
    servers_num = int(sys.stdin.readline())
    for i in range(servers_num):
        temp = sys.stdin.readline()
        temp = re.findall(r'[a-zA-Z0-9.]{1,}', temp)
        serve = [int(i) if i.isdigit() else i for i in temp]
        serves.append(serve)
    virtuals = []
    virtuals_num = int(sys.stdin.readline())
    for i in range(virtuals_num):
        temp = sys.stdin.readline()
        temp = re.findall(r'[a-zA-Z0-9.]{1,}', temp)
        virtual = [int(i) if i.isdigit() else i for i in temp]
        virtuals.append(virtual)

    user_requests = []
    days = int(sys.stdin.readline())
    for i in range(days):
        day_num = int(sys.stdin.readline())
        day_requests = []
        for j in range(day_num):
            temp = sys.stdin.readline()
            temp = re.findall(r'[a-zA-Z0-9.]{1,}', temp)
            request = [int(i) if i.isdigit() else i for i in temp]
            day_requests.append(request)
        user_requests.append(day_requests)
    return serves, virtuals, user_requests



def main():
    # to read standard
    serves, virtuals, user_requests = Get_data()
    # process
    d = daily_situation(serves, virtuals, user_requests)
    d.Virtual_use()
    # to write standard output
    sys.stdout.flush()


if __name__ == "__main__":
    main()
